GPIO中断使用的Sample Code
-
在kernel/drivers/sstar/目录下新增目录test_gpioirq,放入mdrv_gpioirq.c。
-
修改Makefile,增加一行:oby-m += test_gpioirq/
-
Make modules即可生成ko
mdrv_gpioirq.c代码如下:
#include < linux/module.h > #include < linux/moduleparam.h > #include < linux/types.h > #include < linux/gpio.h > #include < linux/interrupt.h > #include "../include/ms_types.h" //#include "../include/infinity6/gpio.h" #include "../include/infinity6e/gpio.h" static int test_gpio_num = PAD_SAR_GPIO3; static struct work_struct work; static irqreturn_t gpio_keys_isr(int irq, void *dev_id) { struct irq_data *data; int gpio_state; int flag; int gpio_num = *(int *)dev_id; gpio_state = gpio_get_value(gpio_num); printk("======gpio_keys_isr:irq=%d gpio num=%d state=%d=====\n",irq,gpio_num,gpio_state); // 需要在中断服务程序中立即处理的动作放在这里 if(!gpio_state) { flag=IRQF_TRIGGER_RISING; } else { flag=IRQF_TRIGGER_FALLING; } data = irq_get_irq_data(irq); data->chip->irq_set_type(data, flag); data->chip->irq_ack(data); schedule_work(&work); return 0; } static void gpioirq_work_func(struct work_struct *work) { printk("Ok!\n"); //不需要在中断服务程序中立即处理,放在工作队列里处理。 } int MDrv_GPIO_To_Irq(U8 u8IndexGPIO); static int __init gpioirq_init(void) { const char *desc = "mdrv_gpioirq"; unsigned long irqflags; int irq, error; error = gpio_request(test_gpio_num, desc); if (error < 0) { printk(KERN_ERR "failed to request GPIO %d, error %d\n", test_gpio_num, error); goto fail2; } error = gpio_direction_input(test_gpio_num); if (error < 0) { printk(KERN_ERR "failed to configure direction for GPIO %d, error %d\n", test_gpio_num, error); goto fail3; } irq = MDrv_GPIO_To_Irq((U8)test_gpio_num); if (irq < 0) { error = irq; printk(KERN_ERR "Unable to get irq number for GPIO %d, error %d\n", test_gpio_num, error); goto fail3; } irqflags = IRQF_ONESHOT | IRQF_TRIGGER_FALLING ; INIT_WORK(&work, gpioirq_work_func); error = request_threaded_irq(irq, NULL, gpio_keys_isr, irqflags, desc, &test_gpio_num); if (error < 0) { printk(KERN_ERR "Unable to claim irq %d; error %d\n", irq, error); goto fail3; } printk(KERN_DEBUG"request_threaded_irq %d success\n",irq); return 0; fail3: gpio_free(test_gpio_num); fail2: return error; } static void __exit gpioirq_exit(void) { int irq=0; irq = MDrv_GPIO_To_Irq((U8)test_gpio_num); printk(KERN_DEBUG"free_irq %d\n",irq); free_irq(irq, &test_gpio_num); gpio_free(test_gpio_num); cancel_work_sync(&work); } module_init(gpioirq_init); module_exit(gpioirq_exit); MODULE_DESCRIPTION("Interrupted GPIO driver"); MODULE_LICENSE("GPL v2");